/*
transformIterator:  Fancy iterator, this iterator brings a value from
                    a collection with a trasformation provided by a
                    transform function on each element in the collection.
    Copyright (C) 2012  Jorge E. A. Atala
                        FuDePAN
    This file is part of the Fui Proyect.

    Fui is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Fui is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Fui.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TRANSFORM_ITERATOR_IMP
#   error This is an internal file, do not include. Include transformIterator.h instead.
#else
namespace fui
{
template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator>::TransformIterator(const Iterator& it, UnaryFunction function)
    :   it(it),
        function(function)
{}

template<class UnaryFunction, class Iterator>
typename TransformIterator<UnaryFunction, Iterator>::Result TransformIterator<UnaryFunction, Iterator>::operator*() const
{
    return function(*it);
}

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator> TransformIterator<UnaryFunction, Iterator>::operator+(const size_t index) const
{
    return TransformIterator<UnaryFunction, Iterator>(it + index, function);
}

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator> TransformIterator<UnaryFunction, Iterator>::operator-(const size_t index) const
{
    return TransformIterator<UnaryFunction, Iterator>(it - index, function);
}

/*
template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator> TransformIterator<UnaryFunction, Iterator>::operator-(const TransformIterator<UnaryFunction, Iterator> other) const
{
    return TransformIterator<UnaryFunction, Iterator>(it - other.it,function);
}
*/

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator>& TransformIterator<UnaryFunction, Iterator>::operator++()
{
    ++it;
    return *this;
}

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator>& TransformIterator<UnaryFunction, Iterator>::operator--()
{
    --it;
    return *this;
}

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator> TransformIterator<UnaryFunction, Iterator>::operator++(const int)
{
    TransformIterator<UnaryFunction, Iterator> output(it++, function);
    return output;
}

template<class UnaryFunction, class Iterator>
TransformIterator<UnaryFunction, Iterator> TransformIterator<UnaryFunction, Iterator>::operator--(const int)
{
    TransformIterator<UnaryFunction, Iterator> output(it--, function);
    return output;
}

template<class UnaryFunction, class Iterator>
bool TransformIterator<UnaryFunction, Iterator>::operator==(const TransformIterator<UnaryFunction, Iterator>& other)const
{
    return it == other.it;
}

template<class UnaryFunction, class Iterator>
bool TransformIterator<UnaryFunction, Iterator>::operator!=(const TransformIterator<UnaryFunction, Iterator>& other)const
{
    return it != other.it;
}

template<class UnaryFunction, class Iterator>
bool TransformIterator<UnaryFunction, Iterator>::operator<(const TransformIterator<UnaryFunction, Iterator>& other)const
{
    return it < other.it;
}
}

#endif
